public class MyBlockQueuemy {
    private int[] arr=new int[1000];//阻塞队列
   volatile private int head=0;//头,即拿元素的下标
   volatile private int tail=0;//尾巴,即放入元素的下标
   volatile private int size=0;//记录当前列表中实际能使用的元素
   synchronized public void put(int value) throws InterruptedException {//加锁,因为是多线程执行
        while (size== arr.length){//当队列满时就阻塞
            this.wait();//一直阻塞,直到消费者消费,使size--.变得不等于arr.length
        }
        //队列不满的情况
        arr[tail]=value;//把put的元素放入数组中,而且是在tail下标中
        tail++;//每次放入之后tail++,以便下次放入数组
        if(tail== arr.length){//当tail已经放到了末尾下标以后,就得从头开始放了,(这是一个循环队列,size只记录队列中的有效元素,对于已经拿出的毫不在意
            tail=0;//重新到0下标
        }
        size++;//每次放入,使得队列中的有效元素加一
        this.notify();//唤醒take方法中的wait(当队列为空时),虽然可能用不上
    }
    synchronized public int take() throws InterruptedException {//加锁,因为是多线程执行
        while (size==0){//当队列为空时,就阻塞状态
                this.wait();//直到put方法放入元素,然后notify唤醒它
        }
        //当队列不为空时
        int value=arr[head];//从头位置开始拿出元素
        head++;//拿完后head加加,到下一位置,让下一次拿
        if(head== arr.length);{//当head到尾巴时就得重新从0开始了
            head=0;
        }
        size--;//拿出后有效元素就减少了
        this.notify();//唤醒put的wait(虽然可能用不上)
        return value;
    }

    public static void main(String[] args) {
        MyBlockQueuemy myBlockQueue=new MyBlockQueuemy();
        //消费者线程
        Thread t1=new Thread(()->{
            //消费
            while (true){
                try {
                    int value  = myBlockQueue.take();
                    System.out.println("消费者:"+value);
                    Thread.sleep(1000);//隔1秒消费一次,
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }
            }
        });
        //生产者线程
        Thread t2=new Thread(()->{
            int value=0;
            while (true){
               try {
                   System.out.println("生产者:"+value);
                   myBlockQueue.put(value);
                   value++;
                   //Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        t1.start();
        t2.start();
        System.out.println("hello");
    }
}
